#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/wait.h>

#define SEM_KEY 1234
#define FILE_PATH "counter.txt"

int sem_id;

void P(int sem_id) {
    struct sembuf sops = {0, -1, 0};
    semop(sem_id, &sops, 1);
}

void V(int sem_id) {
    struct sembuf sops = {0, 1, 0};
    semop(sem_id, &sops, 1);
}

void child_process() {
    FILE *file = fopen(FILE_PATH, "r+");
    if (file == NULL) {
        perror("Error opening file");
        exit(1);
    }

    P(sem_id);

    int count;
    fscanf(file, "%d", &count);
    count++;
    fseek(file, 0, SEEK_SET);
    fprintf(file, "%d", count);
    fflush(file);
    sleep(1);
    V(sem_id);
    fclose(file);
}

int main() {
    sem_id = semget(SEM_KEY, 1, IPC_CREAT | 0666);
    if (sem_id == -1) {
        perror("Error creating semaphore");
        exit(1);
    }

    semctl(sem_id, 0, SETVAL, 1);

    FILE *file = fopen(FILE_PATH, "w");
    if (file == NULL) {
        perror("Error creating file");
        exit(1);
    }
    fprintf(file, "0");
    fclose(file);

    for (int i = 0; i < 20; i++) {
        pid_t pid = fork();
        if (pid == 0) {
            child_process();
            exit(0);
        }
    }

    for (int i = 0; i < 20; i++) {
        wait(NULL);
    }

    semctl(sem_id, 0, IPC_RMID);

    return 0;
}
